/*     */ package com.zimbra.cs.servlet;
/*     */ 
/*     */ import com.zimbra.common.localconfig.KnownKey;
/*     */ import com.zimbra.common.localconfig.LC;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.RemoteIP;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import java.io.IOException;
/*     */ import java.util.concurrent.ConcurrentHashMap;
/*     */ import java.util.concurrent.ConcurrentMap;
/*     */ import java.util.concurrent.Semaphore;
/*     */ import javax.servlet.Filter;
/*     */ import javax.servlet.FilterChain;
/*     */ import javax.servlet.FilterConfig;
/*     */ import javax.servlet.ServletException;
/*     */ import javax.servlet.ServletRequest;
/*     */ import javax.servlet.ServletResponse;
/*     */ import javax.servlet.http.HttpServletRequest;
/*     */ import javax.servlet.http.HttpServletResponse;
/*     */ import javax.servlet.http.HttpSession;
/*     */ import javax.servlet.http.HttpSessionBindingEvent;
/*     */ import javax.servlet.http.HttpSessionBindingListener;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public final class ThrottlingFilter
/*     */   implements Filter
/*     */ {
/*     */   private final ConcurrentMap<String, Semaphore> sid2tracker;
/*     */   
/*     */   public ThrottlingFilter()
/*     */   {
/*  51 */     this.sid2tracker = new ConcurrentHashMap();
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   public void init(FilterConfig config) {}
/*     */   
/*     */ 
/*     */ 
/*     */   public void destroy() {}
/*     */   
/*     */ 
/*     */   public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
/*     */     throws IOException, ServletException
/*     */   {
/*  66 */     HttpServletRequest hreq = (HttpServletRequest)req;
/*  67 */     HttpServletResponse hresp = (HttpServletResponse)resp;
/*  68 */     HttpSession session = hreq.getSession(false);
/*     */     
/*  70 */     int max = LC.servlet_max_concurrent_requests_per_session.intValue();
/*  71 */     if ((session == null) || (max <= 0))
/*     */     {
/*  73 */       chain.doFilter(req, resp);
/*  74 */       return;
/*     */     }
/*     */     
/*  77 */     Semaphore tracker = (Semaphore)this.sid2tracker.get(session.getId());
/*  78 */     if (tracker == null) {
/*  79 */       tracker = new Semaphore(max);
/*  80 */       Semaphore exist = (Semaphore)this.sid2tracker.putIfAbsent(session.getId(), tracker);
/*  81 */       if (exist == null) {
/*  82 */         session.setAttribute(getClass().getName(), new SessionBindingListener(null));
/*     */       }
/*     */       else {
/*  85 */         tracker = exist;
/*     */       }
/*     */     }
/*     */     
/*  89 */     if (tracker.tryAcquire()) {
/*     */       try {
/*  91 */         chain.doFilter(req, resp);
/*     */       } finally {
/*  93 */         tracker.release();
/*     */       }
/*     */     } else {
/*  96 */       new RemoteIP(hreq, ZimbraServlet.getTrustedIPs()).addToLoggingContext();
/*  97 */       ZimbraLog.addToContext("jsessionid", session.getId());
/*  98 */       ZimbraLog.misc.warn("too many concurrent HTTP requests");
/*  99 */       ZimbraLog.clearContext();
/* 100 */       hresp.sendError(503, "too many concurrent HTTP requests");
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */   private class SessionBindingListener
/*     */     implements HttpSessionBindingListener
/*     */   {
/*     */     private SessionBindingListener() {}
/*     */     
/*     */ 
/*     */     public void valueBound(HttpSessionBindingEvent event) {}
/*     */     
/*     */ 
/*     */     public void valueUnbound(HttpSessionBindingEvent event)
/*     */     {
/* 116 */       ThrottlingFilter.this.sid2tracker.remove(event.getSession().getId());
/*     */     }
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/servlet/ThrottlingFilter.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */